package com.gitee.wsl.android.ext.device

import android.content.res.Resources
import android.os.Build
import android.os.Build.VERSION_CODES
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import com.gitee.wsl.android.ext.device.LocaleExt.getLocaleFromCode
import java.util.Locale
import java.util.Objects


object LocaleExt {

    val appLanguage:MutableList<Language> = mutableListOf()

    fun initLanguage(localesRaw: String){
        if (localesRaw.trim { it <= ' ' }.isEmpty()) {
            return
        }
        val locales = localesRaw.split("\n\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        for (locale in locales) {
            appLanguage.add(Language.create(locale))
        }
        appLanguage.sortWith(Comparator { a, b -> a.code.compareTo(b.code) })
    }

    fun followsSystem(): Boolean {
        return AppCompatDelegate.getApplicationLocales().isEmpty
    }

    fun getLocale(): Locale {
        return if (followsSystem()) {
            if (Build.VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
                Locale.getDefault()
            } else if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {
                Resources.getSystem().configuration.locales[0]
            } else {
                Resources.getSystem().configuration.locale
            }
        } else {
            val locale = AppCompatDelegate.getApplicationLocales()[0]
            locale ?: Locale.getDefault()
        }
    }

    fun getLocaleName(): String {
        val locale = getLocale()
        return locale.getDisplayName(locale)
    }

    /*fun getLanguages(context: Context): List<Language> {
        val languages: MutableList<Language> = ArrayList()
        val localesRaw: String = ResUtil.getRawText(context, R.raw.locales)
        if (localesRaw.trim { it <= ' ' }.isEmpty()) {
            return languages
        }
        val locales = localesRaw.split("\n\n".toRegex()).dropLastWhile { it.isEmpty() }
            .toTypedArray()
        for (locale in locales) {
            languages.add(Language(locale))
        }
        //languages.sort()
        return languages
    }*/

    fun getLanguageCode(locales: LocaleListCompat): String? {
        return if (!locales.isEmpty) {
            Objects.requireNonNull(locales[0])?.toLanguageTag()
        } else {
            null
        }
    }

    fun getLocaleFromCode(languageCode: String?): Locale {
        return if (languageCode == null) {
            Locale.getDefault()
        } else try {
            val codeParts = languageCode.split("-".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
            if (codeParts.size > 1) {
                Locale(codeParts[0], codeParts[1])
            } else {
                Locale(languageCode)
            }
        } catch (e: Exception) {
            Locale.getDefault()
        }
    }

    fun getLangFromLanguageCode(languageCode: String): String {
        val codeParts = languageCode.split("-".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        return if (codeParts.size > 1) {
            codeParts[0]
        } else {
            languageCode
        }
    }

    /*fun getLocalizedGrocyDemoDomain(context: Context): String {
        val locale: Locale = getLocale()
        val fullLocaleStr = if (locale.country.isEmpty()) locale.language else locale.language + "-" + locale.country
        var demoDomain: String? = null
        for (language in appLanguage) {
            if (language.code == fullLocaleStr) {
                demoDomain = language.demoDomain
                break
            }
        }
        if (demoDomain == null) {
            for (language in appLanguage) {
                if (language.code == locale.language) {
                    demoDomain = language.demoDomain
                    break
                }
            }
        }
        return demoDomain!!
    }

    fun setLocalizedGrocyDemoInstance(context: Context, sharedPrefs: SharedPreferences) {
        var serverUrl = sharedPrefs.getString(Constants.PREF.SERVER_URL, null)
        if (serverUrl != null && serverUrl.contains("demo.grocy.info")
            && !serverUrl.contains("test-")
        ) {
            val demoDomain = getLocalizedGrocyDemoDomain(context)
            if (demoDomain != null && !serverUrl.contains(demoDomain)) {
                serverUrl = serverUrl.replace(
                    "[a-z]+-?[a-z]*\\.demo\\.grocy\\.info".toRegex(), demoDomain
                )
                sharedPrefs.edit().putString(Constants.PREF.SERVER_URL, serverUrl).apply()
            }
        }
    }*/


}

data class Language(
     val code: String,
     val demoDomain: String,
     val translators: String,
     val name: String
){
    companion object{
        fun create(codeDomainTranslators:String): Language {
            val parts = codeDomainTranslators.split("\n")
            val code = parts[0]
            val demoDomain = parts[1]
            val translators = parts[2]
            val locale: Locale = getLocaleFromCode(code)
            val name = locale.getDisplayName(locale)
            return Language(code, demoDomain, translators, name)
        }
    }
}